import path, { resolve, dirname, join } from "node:path"
import { fileURLToPath } from "node:url";
import { copyDir, getPathFromExecRoot } from "./util.js"
import type { Obj } from "./util.js"
import fs from "fs-extra"
import chalk from "chalk"

// 1 从根目录合并目录，获取路径
export function getPathFromRoot(path: string): string {
  const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "../")
  return join(rootDir, path)
}

// 2 读取文件夹转化为 json 格式并返回
export const dirToJson = (dirPath: string, exclude?: string[]) => {
  const obj: Record<string, string[]> = {}
  for (const file of fs.readdirSync(dirPath, { withFileTypes: true })) {
    if (exclude?.includes(file.name)) continue;
    if (file.isDirectory()) {
      const NAME = file.name
      // 1 获取 - 前面的字段
      const prop = NAME.match(/(\w+)-/)
      // 2 如果 prop 存在
      if (prop) {
        obj[prop[1]] ? obj[prop[1]].push(NAME) : (obj[prop[1]] = [NAME])
      } else {
        obj[NAME] ? obj[NAME].push(NAME) : (obj[NAME] = [NAME])
      }
    }
  }
  return obj
}

// 3 创建项目
export interface Choosed {
  projectName: string;
  framework: string;
  variant: string;
  needTest: boolean;
}
export function createProject(answer: Choosed) {
  // 1 获取相关路径
  const { projectName, variant } = answer
  const srcPath = getPathFromRoot(`template/${variant}`)
  const commonPath = getPathFromRoot(`template/common`)
  const destPath = getPathFromExecRoot(projectName);
  // 2 复制文件夹
  const renameRule: [string[], Obj<string>] = [["_gitignore", "_editorconfig"], { '_': '.' }]
  copyDir(commonPath, destPath, renameRule)
  copyDir(srcPath, destPath, renameRule)
  // 3 修改 package.json 的 name
  changePackageName(destPath, projectName)
  // 4 输出完成信息
  console.log(chalk.blue(`Scaffolding project in ${destPath}...\n`));
  console.log(chalk.red("Done.") + ` Now run:\n`);
  console.log(`${[".", "./"].includes(projectName) ? "" : `      cd ${projectName}\n`}      npm install
      npm run dev\n`);
}
function changePackageName(destPath: string, projectName: string) {
  // 1 获取 package.json
  const packageDestPath = path.join(destPath, "package.json");
  const data = fs.readJSONSync(packageDestPath)
  // 2 修改名
  data.name = projectName
  // 3 重新写入
  fs.writeFileSync(packageDestPath, JSON.stringify(data, null, 2))
}